#include <stdio.h>
// 操作符

struct student{
    char name[10];
    int age;
};

int main()
{
    // 逗号表达式：从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
    int rrr = 1;
    int sss = 2;
    int ttt = (rrr>sss,rrr=sss+10,rrr,sss=rrr+1);// 最后计算sss = 13
    printf("ttt ==== %d\n", ttt); // 输出13
    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    // 下标引用
    // 函数调用
    // 结构成员
    struct student std = {"zhangsan",15};
    printf("name = %s \n", std.name);
    printf("age = %d \n", std.age);
    struct student *p = &std; // 获取结构体的地址
    printf("p name = %s \n", p->name);
    printf("p age = %d \n", p->age);
    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    // 表达式求值

    // 隐式类型转换
    // 计算时 整形提升：表达式中的字符char和短整型short操作数在使用之前被转换为普通整型。按照变量的数据类型的符号位来提升、
    // 保存时 截断
    char a = 3;
    char b = 127;
    char d = a + b;
    printf("c = %d \n",d); // 输出-126，按照补码，先截断，再整形提升，再截断放到d中。
    // 只要参与表达式运算，就会发生整型提升，如+c
    // 运算和打印时会发生整形提升
    char c = 1;
    printf("c = %u\n",sizeof(c));  // 1
    printf("+c = %u\n", sizeof(+c)); // 4
    printf("!c = %u\n", sizeof(!c)); // 4

    // 算术转换
    // long double > double > float > unsigned long int > long int > unsigned int > int ; 算术转换时，后面的往前面转。
    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    // 操作符的属性：1、优先级 2、结合性 3、是否控制求值顺序，比如 ，
    // 结合性：从左往右结合，或者 从右向左结合。
    int e = 10;
    int f = 20;
    int g = f + e * 3;
    printf("g = %d \n", g); // 输出50
    int h = f + e + 3;
    printf("h = %d \n", h);

    // 计算路径不唯一。 这是有问题的表达式
    int i = a*b + c*d + e*f; // 由于*比+的优先级高，只能保证*的计算比+早，但并不能决定第三个*比第一个+早执行。

    int l = 10;
    int k = l + --l; // 操作符的优先级只能决定自减的运算在+的运算的前面，但是我们并没有办法得知，+操作符左操作数的获取在右操作数之前还是之后求值，结果不可预测。不同编译器处理可能不同。
    printf("k = %d \n", k); // 输出18，先--，再+

    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    return 0;
}